<template>
    <div class="permission-page">
        <div class="card-wrap mb10 animate-on-enter">
            <a-space wrap>
                <a-button type="primary" :icon="h(PlusCircleOutlined)" @click="onAddMenu">新增</a-button>
            </a-space>
        </div>
        <div class="card-wrap animate-on-enter animate-delay-1">
            <DataList ref="DataListRef" :api="getAllMenus" :deleteApi="deleteMenus" :columns="tableColumns"
                @action="handleAction"></DataList>
        </div>
        <!-- 新增菜单弹窗 -->
        <a-modal v-model:open="openMenuModal" title="新增菜单" :maskClosable="false" :footer="null">
        <a-form ref="menuFormRef" :model="formState" :label-col="labelCol" :rules="rules" @finish="onMenuSubmit">
            <a-form-item label="类型" name="type">
                <a-radio-group v-model:value="formState.type">
                    <a-radio :value="1">菜单</a-radio>
                    <a-radio :value="2">接口</a-radio>
                </a-radio-group>
            </a-form-item>
            <a-form-item label="父级菜单" name="parent_id">
                <a-tree-select v-model:value="formState.parent_id" placeholder="默认为顶级菜单" :tree-data="parentMenus"
                    :field-names="{ label: 'title', value: 'id', children: 'children' }"
                    tree-default-expand-all></a-tree-select>
            </a-form-item>
            <a-form-item :label="formState.type === 1 ? '菜单标题' : '接口名称'" name="title">
                <a-input v-model:value="formState.title" :placeholder="formState.type === 1 ? '请填写菜单标题' : '请填写接口名称'" />
            </a-form-item>
            <a-form-item v-if="formState.type === 1" label="菜单标识" name="name">
                <a-input v-model:value="formState.name" :placeholder="formState.type === 1 ? '请填写菜单标识' : '请填写接口标识'" />
            </a-form-item>
            <a-form-item :label="formState.type === 1 ? '访问URL' : '接口路径'" name="path">
                <a-input v-model:value="formState.path" :placeholder="formState.type === 1 ? '请填写访问URL' : '请填写接口路径'" />
            </a-form-item>
            <a-form-item label="组件路径" name="component" v-if="formState.type === 1">
                <a-input v-model:value="formState.component" placeholder="请填写组件路径" />
            </a-form-item>
            <a-form-item label="菜单图标" name="icon" v-if="formState.type === 1">
                <div class="icon-selector">
                    <div class="selected-icon" @click="showIconPicker = !showIconPicker">
                        <div class="icon-display">
                            <component v-if="formState.icon" :is="getIconComponent(formState.icon)" style="font-size: 16px;" />
                            <span v-else class="placeholder">请选择菜单图标</span>
                        </div>
                        <DownOutlined :style="{ transform: showIconPicker ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 0.3s' }" />
                    </div>
                    <div v-if="showIconPicker" class="icon-picker">
                        <div class="icon-search">
                            <a-input v-model:value="iconSearchText" placeholder="搜索图标" prefix="🔍" />
                        </div>
                        <div class="icon-grid">
                            <div v-for="icon in filteredIcons" :key="icon.value"
                                :class="['icon-item', { 'selected': formState.icon === icon.value }]"
                                @click="selectIcon(icon.value)">
                                <component :is="icon.value" />
                                <span class="icon-name">{{ icon.label }}</span>
                            </div>
                        </div>
                        <div class="icon-actions">
                            <a-button size="small" @click="clearIcon">清除</a-button>
                            <a-button size="small" type="primary" @click="showIconPicker = false">确定</a-button>
                        </div>
                    </div>
                </div>
            </a-form-item>
            <a-form-item label="排序" name="sort">
                <a-input-number v-model:value="formState.sort" style="width: 100%;" placeholder="请填写排序" />
            </a-form-item>
            <a-form-item label="状态" name="status">
                <a-radio-group v-model:value="formState.status">
                    <a-radio :value="1">开启</a-radio>
                    <a-radio :value="0">禁用</a-radio>
                </a-radio-group>
            </a-form-item>
            <a-form-item :wrapper-col="{ span: 14, offset: 4 }">
                <a-button type="primary" html-type="submit">保存</a-button>
                <a-button style="margin-left: 10px" @click="openMenuModal = false">取消</a-button>
            </a-form-item>
        </a-form>
        </a-modal>
    </div>
</template>
<script setup>
import { onMounted, h, ref, reactive, nextTick, computed, getCurrentInstance } from 'vue';
import { getAllMenus, saveMenus, deleteMenus } from '@/api/auth.js'
import { PlusCircleOutlined, DownOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
/**
 *页面全局变量
*/
const tableColumns = [
    {
        title: '标题',
        dataIndex: 'title',
        width: 200
    },
    {
        title: '权限标识',
        dataIndex: 'name'
    },
    {
        title: '访问URL/API',
        dataIndex: 'path',
        width: 150
    },
    {
        title: '组件路径',
        dataIndex: 'component',
        width: 150
    },
    {
        title: '权限',
        dataIndex: 'permission'
    },
    {
        title: '状态',
        dataIndex: 'status'
    },
    {
        title: '创建时间',
        dataIndex: 'created_at'
    },
    {
        type: 'action',
        title: "操作",
        align: 'center',
        options: [
            {
                type: 'delete',
                key: 'delete',
                title: '删除'
            },
            {
                key: 'edit',
                title: '编辑'
            }
        ]
    }
]

const rules = {
    type: [
        {
            required: true,
            message: '请选择类型',
            trigger: 'change',
        }
    ],
    title: [
        {
            required: true,
            message: '请填写标题',
            trigger: 'change',
        },
        {
            min: 2,
            max: 20,
            message: '长度为2到20个字符',
            trigger: 'change',
        },
    ],
    name: [
        {
            required: true,
            message: '请填写标识',
            trigger: 'change',
        }
    ],
    path: [
        {
            required: true,
            message: '请填写路径',
            trigger: 'change',
        }
    ],
    component: [
        {
            required: true,
            message: '请填写组件路径',
            trigger: 'change',
        }
    ]
}

const labelCol = {
    style: {
        width: '70px',
    },
};

const openMenuModal = ref(false)
const parentMenus = ref([])
const menuFormRef = ref();
const DataListRef = ref();
const showIconPicker = ref(false)
const iconSearchText = ref('')
const formState = reactive({
    id: null,
    type: 1,
    parent_id: "0",
    title: "",
    name: "",
    path: "",
    component: "",
    icon: "",
    sort: 0,
    status: 1,
})

// 获取全局注册的图标
const instance = getCurrentInstance()
const antIcons = instance?.appContext.config.globalProperties.$antIcons || {}

// 生成图标选项数组
const iconOptions = Object.keys(antIcons)
    .filter(key => key.endsWith('Outlined') && key !== 'createFromIconfontCN')
    .map(key => ({
        value: key,
        label: key.replace('Outlined', '').replace(/([A-Z])/g, ' $1').trim(),
        component: key
    }))
    .sort((a, b) => a.label.localeCompare(b.label))

// 计算属性：过滤图标
const filteredIcons = computed(() => {
    if (!iconSearchText.value) {
        return iconOptions
    }
    return iconOptions.filter(icon =>
        icon.label.toLowerCase().includes(iconSearchText.value.toLowerCase()) ||
        icon.value.toLowerCase().includes(iconSearchText.value.toLowerCase())
    )
})


/**
 *页面生命周期
*/
onMounted(() => {
    getAllMenusData()
})


/**
 *页面函数
*/

function onAddMenu() {
    openMenuModal.value = true

    if (menuFormRef.value) menuFormRef.value.resetFields()
}

function getAllMenusData() {
    getAllMenus().then(res => {
        if (res.code == 200) {

            const defaultObj = {
                id: "0",
                title: '顶级菜单',
                disabled: true
            }

            parentMenus.value = [defaultObj, ...res.result];
        }
    })
}

function onMenuSubmit() {
    saveMenus(formState).then(res => {
        if (res.code == 200) {
            message.success(res.message)
            openMenuModal.value = false
            DataListRef.value.refreshData()
        }
    })
}

function handleAction(row, data) {

    if (row.key == 'edit') {
        menuEdit(data)
    }
}

function menuEdit(data) {
    openMenuModal.value = true;

    nextTick(() => {
        Object.assign(formState, data)
    })
}

// 图标选择器相关方法
function selectIcon(iconValue) {
    formState.icon = iconValue
    showIconPicker.value = false
    iconSearchText.value = ''
}

function clearIcon() {
    formState.icon = ''
    showIconPicker.value = false
    iconSearchText.value = ''
}

function getIconComponent(iconValue) {
    return iconValue
}

function getIconLabel(iconValue) {
    const icon = iconOptions.find(item => item.value === iconValue)
    return icon ? icon.label : ''
}
</script>
<style lang="less" scoped>
.icon-selector {
    position: relative;
    width: 100%;

    .selected-icon {
        display: flex;
        align-items: center;
        padding: 4px 11px;
        min-height: 32px;
        border: 1px solid #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        background: #fff;
        transition: all 0.3s;
        font-size: 14px;
        line-height: 1.5715;

        &:hover {
            border-color: #40a9ff;
        }

        &:focus {
            border-color: #40a9ff;
            box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
            outline: 0;
        }

        .icon-display {
            flex: 1;
            display: flex;
            align-items: center;
            
            .anticon {
                color: #000000d9;
            }
            
            .placeholder {
                color: #bfbfbf;
            }
        }
        
        > .anticon {
            color: #bfbfbf;
            font-size: 12px;
            transition: transform 0.3s;
            margin-left: 8px;
        }
    }

    .icon-picker {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        z-index: 1050;
        background: #fff;
        border: 1px solid #d9d9d9;
        border-radius: 6px;
        box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
        max-height: 320px;
        overflow: hidden;
        margin-top: 4px;

        .icon-search {
            padding: 12px;
            border-bottom: 1px solid #f0f0f0;

            .ant-input {
                border-radius: 6px;
            }
        }

        .icon-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
            gap: 4px;
            padding: 8px;
            max-height: 200px;
            overflow-y: auto;

            &::-webkit-scrollbar {
                width: 6px;
            }

            &::-webkit-scrollbar-thumb {
                background: #d9d9d9;
                border-radius: 3px;
            }

            .icon-item {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                padding: 8px 4px;
                border: 1px solid transparent;
                border-radius: 6px;
                cursor: pointer;
                transition: all 0.2s;
                background: #fff;
                min-height: 60px;

                &:hover {
                    border-color: #d9d9d9;
                    background: #f5f5f5;
                }

                &.selected {
                    border-color: #1890ff;
                    background: #e6f7ff;
                    color: #1890ff;
                }

                .anticon {
                    font-size: 18px;
                    margin-bottom: 4px;
                }

                .icon-name {
                    font-size: 10px;
                    text-align: center;
                    line-height: 1.2;
                    word-break: break-all;
                    max-width: 100%;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    display: -webkit-box;
                    -webkit-line-clamp: 2;
                    -webkit-box-orient: vertical;
                }
            }
        }

        .icon-actions {
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: 8px;
            padding: 8px 12px;
            border-top: 1px solid #f0f0f0;
            background: #fafafa;

            .ant-btn {
                border-radius: 6px;
            }
        }
    }
}
</style>